#include "protocol.h"

#include "cJSON.h"
#include "md5.h"
#include "esp_log.h"
#include "hex.h"
#include "aes.h"

#include "esp_random.h"
#include "time.h"
#include "esp_mac.h"

extern ApproxyCfgST_t *approxy_cfg_st;

char gl_szUserAgent[128] = {0};//用户设备码

int _debug = 1;
/** 4位版本 				*/
Bit8 version = 0x40; // 0100 0000 
/** 4位首部长度 	固定为5 */
Bit8 headlen = 0x05; // 0000 0101 
Bit8 sign =  SIGN_010;
Bit8 offset = 0x00;
Bit8 pto = PTO_LUT;
Bit8 ttl = TTL_255;

/** 数据包计数器 **/
Bit16 nGLdataSerial = 0;// 1 ~ 0xFFFF

/** 获取UserAgent **/
Bit8 * szUserAgentSerial = NULL;

unsigned char IV_03[16] = Config_Aes_IV_03;

/** 共享变量 **/
extern char approxy_db_file[];
extern char approxy_db_table[];
extern int	 _ab_enableAB;
extern char _ab_deviceCode[];

static const char *TAG = "protocol";

/** 生成握手数据包 **/
int NewLutSacSYNPackage(LutPackage_t *_LutPackage){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pJson = NULL;
	// cJSON* tmp = NULL;
	Bit8  *szUserAgent = NULL;
	Bit8  *szNonce = NULL;
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	MallocBuf(Bit8,szUserAgent,40);
	MallocBuf(Bit8,szNonce,20);

	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	sprintf_s((char *)szNonce,16,"%08X",nNonce);

	pJson = fn_cJSON_CreateObject();
//	fn_RYN_LOG_DEBUG("NewLutSacSYNPackage:szUserAgent:%s,timeMills:%lld,nNonce:%d",szUserAgent,timeMills,nNonce);
//	fn_RYN_LOG_DEBUG("NewLutSacSYNPackage:szUserAgentSerial:%s",szUserAgent);

	fn_cJSON_AddStringToObject(pJson,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pJson,"szUserAgentSerial",(char *)szUserAgent);
//	fn_cJSON_AddNumberToObject(pJson,"nTimestamp",(double)timeMills);
	json = fn_cJSON_PrintUnformatted(pJson);

	fn_RYN_LOG_DEBUG(TAG,"NewLutSacSYNPackage:fn_cJSON_PrintUnformatted:%s",json);
	nRet = NewLutPackage(_LutPackage,SAC_SYN,saddr,dataSerial,json,strlen(json));

	FreeBuf(szNonce);
	FreeBuf(szUserAgent);
	FreeBuf(json);
	fn_cJSON_Delete(pJson);
	return nRet;
}

/** 生成授权数据包 **/
int NewLutSacSAUPackage(LutPackage_t *_LutPackage,Bit8 * szUserName,Bit8 * szPassword,Bit8 *synCode){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;


	Bit8  *szUserAgent = NULL;
	Bit8  *szNonce = NULL;
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;

	pRoot = fn_cJSON_CreateObject();
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();

	MallocBuf(Bit8,szUserAgent,40);
	MallocBuf(Bit8,szNonce,20);
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);

	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,16,"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserName",(char *)szUserName);
	fn_cJSON_AddStringToObject(pRoot,"szPassword",(char *)szPassword);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szSynCode",(char *)synCode);
	//fn_RYN_LOG_DEBUG("NewLutSacSAUPackage:szUserAgentSerial:%s, nTimestamp:%lld, szNonce:%s, szUserName:%s, szPassword:%s",szUserAgent,timeMills,szNonce,szUserName,szPassword);

	json = fn_cJSON_PrintUnformatted(pRoot);
	fn_RYN_LOG_DEBUG(TAG,"NewLutSacSAUPackage:fn_cJSON_PrintUnformatted:%s",json);

	FreeBuf(szNonce);
	FreeBuf(szUserAgent);
//	fn_cJSON_Minify(json);

	nRet = NewLutPackage(_LutPackage,SAC_SAU,saddr,dataSerial,json,strlen(json));

	FreeBuf(json);
	fn_cJSON_Delete(pRoot);

	return nRet;
}

/** 生成心跳数据包 **/
int NewLutSacSHBPackage(LutPackage_t *_LutPackage,Bit8 * szSessionID){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szSessionID",(char *)szSessionID);
	json = fn_cJSON_PrintUnformatted(pRoot);
//	fn_cJSON_Minify(json);
	fn_cJSON_Delete(pRoot);
	// if(_debug)
	// 	LOG_DEBUG(TAG,"json = %s\n",json);

	nRet = NewLutPackage(_LutPackage,SAC_SHB,saddr,dataSerial,json,strlen(json));
	FreeBuf(json);
	return nRet;
}

/** 生成指令数据包 **/
int NewLutSacSCMPackage(LutPackage_t *_LutPackage,Bit8 * szSCM,Bit8 * szSCMDA,Bit8 * szSessionID){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szSCM",(char *)szSCM);
	fn_cJSON_AddStringToObject(pRoot,"szSCMDA",(char *)szSCMDA);
	fn_cJSON_AddStringToObject(pRoot,"szSessionID",(char *)szSessionID);
	json = fn_cJSON_PrintUnformatted(pRoot);
//	fn_cJSON_Minify(json);
	if(pRoot){
		fn_cJSON_Delete(pRoot);
	}
	// if(_debug)
	// 	LOG_DEBUG(TAG,"json = %s\n",json);

	nRet = NewLutPackage(_LutPackage,SAC_SCM,saddr,dataSerial,json,strlen(json));
	return nRet;
}

/** 生成即时消息数据包 **/
int NewLutSacMSGPackage(LutPackage_t *_LutPackage,Bit8 * szMSG,Bit8 * szMSGDA,Bit8 * szSessionID){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szMSG",(char *)szMSG);
	fn_cJSON_AddStringToObject(pRoot,"szMSGDA",(char *)szMSGDA);
	fn_cJSON_AddStringToObject(pRoot,"szSessionID",(char *)szSessionID);
	json = fn_cJSON_PrintUnformatted(pRoot);
//	fn_cJSON_Minify(json);
	if(pRoot){
		fn_cJSON_Delete(pRoot);
	}
	// if(_debug)
	// 	LOG_DEBUG(TAG,"json = %s\n",json);

	nRet = NewLutPackage(_LutPackage,SAC_IM,saddr,dataSerial,json,strlen(json));
	return nRet;
}

/** 生成免授权指令包(短连接) **/
int NewLutSacSNUPackage(LutPackage_t *_LutPackage,Bit8 * szSNU,Bit8 * szSNUDA){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szSNU",(char *)szSNU);
	fn_cJSON_AddStringToObject(pRoot,"szSNUDA",(char *)szSNUDA);
	json = fn_cJSON_PrintUnformatted(pRoot);
//	fn_cJSON_Minify(json);

	//if(_debug)
	//	DEBUG("json = %s\n",json);

	nRet = NewLutPackage(_LutPackage,SAC_SNU,saddr,dataSerial,json,strlen(json));

	FreeBuf(json);
	fn_cJSON_Delete(pRoot);
	//_LutPackage->_LutPackageLen = strlen(json)+1;
	//_LutPackage->_LutPackage = (Bit8 *)malloc(_LutPackage->_LutPackageLen);
	//memset(_LutPackage->_LutPackage,0,_LutPackage->_LutPackageLen);
	//memcpy_s(_LutPackage->_LutPackage,_LutPackage->_LutPackageLen,json,_LutPackage->_LutPackageLen);
	return nRet;
}


/** 生成打洞指令包 **/
int NewLutSacSDGPackage(LutPackage_t *_LutPackage,Bit8 * szDIG,Bit8 * szDIGDA){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szSDG",(char *)szDIG);
	fn_cJSON_AddStringToObject(pRoot,"szSDGDA",(char *)szDIGDA);
	json = fn_cJSON_PrintUnformatted(pRoot);
//	fn_cJSON_Minify(json);

	//if(_debug)
	//	DEBUG("json = %s\n",json);

	nRet = NewLutPackage(_LutPackage,SAC_SDG,saddr,dataSerial,json,strlen(json));

	FreeBuf(json);
	fn_cJSON_Delete(pRoot);
	//_LutPackage->_LutPackageLen = strlen(json)+1;
	//_LutPackage->_LutPackage = (Bit8 *)malloc(_LutPackage->_LutPackageLen);
	//memset(_LutPackage->_LutPackage,0,_LutPackage->_LutPackageLen);
	//memcpy_s(_LutPackage->_LutPackage,_LutPackage->_LutPackageLen,json,_LutPackage->_LutPackageLen);
	return nRet;
}

/** 生成免授权指令包(长连接) **/
int NewLutSacSNBPackage(LutPackage_t *_LutPackage,Bit8 * szSNU,Bit8 * szSNUDA){
	int nRet = 0;
	Bit32 saddr = 0;
	Bit16 dataSerial = 0;
	cJSON* pRoot = NULL;
	Bit8  szUserAgent[40] = {0};
	Bit8  szNonce[16] = {0};
	int nUserAgentLen = 0;
	int nNonce = 0;
	char * json = NULL;
	unsigned long long  timeMills = 0;
	saddr = GetUserAgentLocalIP();
	dataSerial = GetDataSerial();
	GetNativeDeviceCode(szUserAgent,&nUserAgentLen);
	pRoot = fn_cJSON_CreateObject();
	timeMills = fn_GetSystemTime();
	nNonce = LutRandom(0xFFFF,0x10);
	sprintf_s((char *)szNonce,sizeof(szNonce),"%08X",nNonce);
	fn_cJSON_AddStringToObject(pRoot,"szUserAgentSerial",(char *)szUserAgent);
	fn_cJSON_AddNumberToObject(pRoot,"nTimestamp",(double)timeMills);
	fn_cJSON_AddStringToObject(pRoot,"szNonce",(char *)szNonce);
	fn_cJSON_AddStringToObject(pRoot,"szSNB",(char *)szSNU);
	fn_cJSON_AddStringToObject(pRoot,"szSNBDA",(char *)szSNUDA);
	json = fn_cJSON_PrintUnformatted(pRoot);

	nRet = NewLutPackage(_LutPackage,SAC_SNB,saddr,dataSerial,json,strlen(json));

	FreeBuf(json);
	fn_cJSON_Delete(pRoot);
	return nRet;
}
/** 协议头字节码转协议头结构体（前提：已经验证过校验和） **/
int NewLutProtocolHead(ProtocolHead_t *_protocolHead,Bit8 * _Buf,int nBufLen){
	// 计算协议头16位首部校验和
	Bit16 cksum = LutCkSum((Bit8 *)_Buf,nBufLen);
	PrintLutByte("_Buf  :",_Buf,nBufLen);
	//printf("~cksum = %04X\n",~cksum);
	if((Bit16)(~cksum) == 0xFFFF){
		Bit16 _bit16 = 0;
		Bit32 _bit32 = 0;
		memcpy_s(&_protocolHead->version,1,&_Buf[0],1);
		memcpy_s(&_protocolHead->tos,1,&_Buf[1],1);

		memcpy_s(&_bit16,2,&_Buf[2],2);
		_protocolHead->total = _bit16 >> 0x08 | _bit16 << 0x08;

		memcpy_s(&_bit16,2,&_Buf[4],2);
		_protocolHead->serial = _bit16 >> 0x08 | _bit16 << 0x08;

		memcpy_s(&_bit16,2,&_Buf[6],2);
		_protocolHead->sign = _bit16 >> 0x08 | _bit16 << 0x08;

		memcpy_s(&_protocolHead->ttl,1,&_Buf[8],1);
		memcpy_s(&_protocolHead->pto,1,&_Buf[9],1);

		memcpy_s(&_bit16,2,&_Buf[10],2);
		_protocolHead->cksum = _bit16 >> 0x08 | _bit16 << 0x08;

		memcpy_s(&_bit32,4,&_Buf[12],4);
		_protocolHead->saddr = ((_bit32 & 0xFF)<<24)|((_bit32>> 8 & 0xFF)<<16)|((_bit32>> 16 & 0xFF)<<8)|(_bit32>> 24) & 0xFF;
		
		memcpy_s(&_protocolHead->sac,4,&_Buf[16],4);

		return 0;
	}else{
		return -1;
	}
}



int NewLutPackage(LutPackage_t *_LutPackage,Bit32 sac,Bit32 saddr,Bit16 dataSerial,char *data,int dataLen){
	int nRet = 0;
	int rdom = 0;
	int i = 0;
	int _ProtocolHeadLen = 0;
	unsigned char *pSecurityKeyP = NULL;
	char *_ProtocolHead = NULL;
	char *_ProtocolHeadP = NULL;
	unsigned char *_BodyDDataP = NULL;
	// char _bit32c[16] = {0};
	// char _tt[2] = {0};
	Bit16 _bit16 = 0;
	Bit32 _bit32 = 0;
	SecurityKey_t *pSecurityKey = NULL;
	ProtocolHead_t *pProtocolHead = NULL;
	Signature_t *pSignature = NULL;
	BodyData_t *pBodyData = NULL;
	BodyData_t *pEncryptBodyData = NULL;
	Bit8 * _LutPackageP = NULL;
	MD5Context_t md5Ctx;
	
	//////////////////////////////////////////////////////////////////////////
	//1. 生成随机AESKEY
	pSecurityKey = (SecurityKey_t *)malloc(sizeof(SecurityKey_t));
	memset(pSecurityKey,0,sizeof(SecurityKey_t));
	pSecurityKey->SecurityKeyLen = 16;
	pSecurityKey->pSecurityKeyData = (unsigned char *)malloc(pSecurityKey->SecurityKeyLen);
	memset(pSecurityKey->pSecurityKeyData,0,sizeof(pSecurityKey->SecurityKeyLen));
	pSecurityKeyP = pSecurityKey->pSecurityKeyData;
	for(i=0;i<4;i++){
		rdom = LutRandom(0xFFFF,(i+1 * rdom)<<3);
		rdom*=rdom;
		//printf("%d rand = %04X",sizeof(rdom),rdom);
		_bit32 = ((rdom & 0xFF)<<24)|((rdom>> 8 & 0xFF)<<16)|((rdom>> 16 & 0xFF)<<8)|(rdom>> 24) & 0xFF;
		rdom = _bit32;
		memcpy_s(pSecurityKeyP,sizeof(rdom),(&rdom),sizeof(rdom));
		//printf(" => %X\n",pSecurityKeyP);
		pSecurityKeyP += sizeof(rdom);
	}
	//printf("数据密钥：");
	//for(i=0;i<pSecurityKey->SecurityKeyLen;i++){
	//	printf("%02X ",(pSecurityKey->pSecurityKeyData)[i]);
	//}
	//printf("\n");


	//////////////////////////////////////////////////////////////////////////
	// 2. 加密数据主体
	pBodyData = (BodyData_t *)malloc(sizeof(BodyData_t));
	memset(pBodyData,0,sizeof(BodyData_t));
	pBodyData->BodyDataLen = dataLen+2;

	pBodyData->pBodyDData = (unsigned char *)malloc(pBodyData->BodyDataLen);
	memset(pBodyData->pBodyDData,0,pBodyData->BodyDataLen);
	_bit16 = ((dataLen % 65536 )>>8) | ((dataLen % 65536) << 8);
	_BodyDDataP = pBodyData->pBodyDData;
	memcpy_s(_BodyDDataP,sizeof(Bit16),&_bit16,sizeof(Bit16));
	_BodyDDataP += sizeof(Bit16);
	memcpy_s(_BodyDDataP,dataLen,data,dataLen);

	//printf("正文数据长度：%d\n",dataLen);
	//printf("正文数据：%s\n",pBodyData->pBodyDData+2);
	pEncryptBodyData = (BodyData_t *)malloc(sizeof(BodyData_t));
	memset(pEncryptBodyData,0,sizeof(BodyData_t));

	AES_Init((char *)pSecurityKey->pSecurityKeyData);

	//printf("AESKEY：");
	//for(i=0;i<pSecurityKey->SecurityKeyLen;i++){
	//	printf("%02X ",(pSecurityKey->pSecurityKeyData)[i]);
	//}
	//printf("\n");
	//
	//printf("IV：");
	//for(i=0;i<sizeof(pIV);i++){
	//	printf("%02X ",(pIV)[i]);
	//}
	//printf("\n");


	AES_Encrypt_Len(pBodyData->BodyDataLen,(unsigned int *)(&pEncryptBodyData->BodyDataLen));
	pEncryptBodyData->pBodyDData = (unsigned char *)malloc(pEncryptBodyData->BodyDataLen);
	memset(pEncryptBodyData->pBodyDData,0,pEncryptBodyData->BodyDataLen);
	AES_Encrypt(pBodyData->pBodyDData,(int )pBodyData->BodyDataLen,pEncryptBodyData->pBodyDData,(int )pEncryptBodyData->BodyDataLen,IV_03);
	PrintLutByte("原本数据",pBodyData->pBodyDData,pBodyData->BodyDataLen);
	PrintLutByte("加密数据",pEncryptBodyData->pBodyDData,pEncryptBodyData->BodyDataLen);
	if(0){
		int i = 0;
		int step = 1024;
		fn_RYN_LOG_DEBUG(TAG,"\nbodyDataLEN: %d",pEncryptBodyData->BodyDataLen);
		for(i = 0; i< pEncryptBodyData->BodyDataLen;i+=step){

			if(i+step >= pEncryptBodyData->BodyDataLen){
				step = pEncryptBodyData->BodyDataLen - i;
			}
			//fn_PrintByteArray("TT",(char *)pEncryptBodyData->pBodyDData + i,step);
		}
	}
	//if(BytePrintDebug){
	//	unsigned char * decryptByte = NULL;
	//	MallocBuf(unsigned char,decryptByte,pEncryptBodyData->BodyDataLen);
	//	fn_AES_Decrypt(decryptByte,pEncryptBodyData->pBodyDData,pEncryptBodyData->BodyDataLen,IV_03);
	//	PrintLutByte("解密数据",decryptByte,pEncryptBodyData->BodyDataLen);
	//	printf("自解密文本：%s\n",decryptByte+2);
	//	FreeBuf(decryptByte);
	//
	//}
	//if(_debug){
	//	unsigned char* _data = NULL;
	//	MallocBuf(unsigned char,_data,pEncryptBodyData->BodyDataLen);
	//	fn_AES_Decrypt((unsigned char *)_data,(unsigned char *)pEncryptBodyData->pBodyDData,pEncryptBodyData->BodyDataLen,IV_03);
	//	PrintLutByte("222解密之后主体数据",_data,pEncryptBodyData->BodyDataLen);
	//}
	//////////////////////////////////////////////////////////////////////////
	// 3. 计算加密后的数据主体签名
	pSignature = (Signature_t *)malloc(sizeof(Signature_t));
	pSignature->SignatureLen = 16;
	pSignature->pSignatureData = (unsigned char *)malloc(pSignature->SignatureLen);
	memset(pSignature->pSignatureData,0,pSignature->SignatureLen);

	MD5Init(&md5Ctx);
	MD5Update(&md5Ctx,pEncryptBodyData->pBodyDData,pEncryptBodyData->BodyDataLen);
	MD5Final(pSignature->pSignatureData,&md5Ctx);

	PrintLutByte("数据签名",pSignature->pSignatureData,pSignature->SignatureLen);

	//////////////////////////////////////////////////////////////////////////
	// 4. 拼接协议头部
	_ProtocolHeadLen = (version>>0x04) * headlen;
	pProtocolHead = (ProtocolHead_t *)malloc(sizeof(ProtocolHead_t));
	pProtocolHead->version = version|headlen;
	pProtocolHead->tos = TOS_0000;
	pProtocolHead->total = _ProtocolHeadLen + 32 + pEncryptBodyData->BodyDataLen;
	pProtocolHead->serial = dataSerial;
	pProtocolHead->sign = sign<<0x0D | offset;
	pProtocolHead->ttl = ttl;
	pProtocolHead->pto = pto;
	pProtocolHead->cksum = 0x00;
	pProtocolHead->saddr = GetUserAgentLocalIP();
	pProtocolHead->sac = sac;

	if(1){
		int total_data_len = _ProtocolHeadLen + 32 + pEncryptBodyData->BodyDataLen;
		int total = total_data_len % 65536;
		int total_count = total_data_len / 65536;
		if(total_data_len >= 65536){
			pProtocolHead->total = total;
			//fn_RYN_LOG_DEBUG("serial1: %d",pProtocolHead->serial);
			pProtocolHead->serial = (0x8000 | total_count);
			//fn_RYN_LOG_DEBUG("serial2: %d",pProtocolHead->serial);
		}
	}

	//fn_RYN_LOG_DEBUG("数据包总长度 = %d, serial: %d",pProtocolHead->total,(pProtocolHead->serial & 0x0FFF));
	//pProtocolHead->cksum = LutCkSum((Bit8 *)pProtocolHead,_ProtocolHeadLen);
	//_bit16 = (pProtocolHead->total>>0x08) | (pProtocolHead->total<<0x08);
	//memcpy_s(_tt,2,&_bit16,2);
	//for(i=0;i<2;i++){
	//	printf("%02X ",_tt[i]);
	//}
	//printf("\n");
	//printf("IPP = ");
	//printf("%08X ",pProtocolHead->saddr);
	//printf("\n");

	_ProtocolHead = (char *)malloc(_ProtocolHeadLen);
	_ProtocolHeadP = _ProtocolHead;
	memset(_ProtocolHead,0,_ProtocolHeadLen);
	memcpy_s(_ProtocolHeadP,sizeof(Bit8),&pProtocolHead->version,sizeof(Bit8));
	_ProtocolHeadP += sizeof(Bit8);
	memcpy_s(_ProtocolHeadP,sizeof(Bit8),&pProtocolHead->tos,sizeof(Bit8));
	_ProtocolHeadP += sizeof(Bit8);

	_bit16 = (pProtocolHead->total>>0x08) | (pProtocolHead->total<<0x08);
	memcpy_s(_ProtocolHeadP,sizeof(Bit16),&_bit16,sizeof(Bit16));
	_ProtocolHeadP += sizeof(Bit16);

	_bit16 = (pProtocolHead->serial>>0x08) | (pProtocolHead->serial<<0x08);
	memcpy_s(_ProtocolHeadP,sizeof(Bit16),&_bit16,sizeof(Bit16));
	_ProtocolHeadP += sizeof(Bit16);

	_bit16 = (pProtocolHead->sign>>0x08) | (pProtocolHead->sign<<0x08);
	memcpy_s(_ProtocolHeadP,sizeof(Bit16),&_bit16,sizeof(Bit16));
	_ProtocolHeadP += sizeof(Bit16);

	memcpy_s(_ProtocolHeadP,sizeof(Bit8),&pProtocolHead->ttl,sizeof(Bit8));
	_ProtocolHeadP += sizeof(Bit8);

	memcpy_s(_ProtocolHeadP,sizeof(Bit8),&pProtocolHead->pto,sizeof(Bit8));
	_ProtocolHeadP += sizeof(Bit8);


	_bit16 = (pProtocolHead->cksum>>0x08) | (pProtocolHead->cksum<<0x08);
	memcpy_s(_ProtocolHeadP,sizeof(Bit16),&_bit16,sizeof(Bit16));
	_ProtocolHeadP += sizeof(Bit16);

	_bit32 = ((pProtocolHead->saddr & 0xFF)<<24)|((pProtocolHead->saddr>> 8 & 0xFF)<<16)|((pProtocolHead->saddr>> 16 & 0xFF)<<8)|(pProtocolHead->saddr>> 24) & 0xFF;
	//printf("_bit32 = %08X\n",_bit32);
	//printf("=== %02X\n",_bit32);
	memcpy_s(_ProtocolHeadP,sizeof(Bit32),&_bit32,sizeof(Bit32));
	_ProtocolHeadP += sizeof(Bit32);

	memcpy_s(_ProtocolHeadP,sizeof(Bit32),&pProtocolHead->sac,sizeof(Bit32));
	_ProtocolHeadP += sizeof(Bit32);

	/** 重新计算cksum **/
	pProtocolHead->cksum = LutCkSum((Bit8 *)_ProtocolHead,_ProtocolHeadLen);
	_bit16 = (pProtocolHead->cksum>>0x08) | (pProtocolHead->cksum<<0x08);

	/** 将cksum填充到指定位置 **/
	_ProtocolHeadP = _ProtocolHead;
	memcpy_s(_ProtocolHeadP+10,sizeof(Bit16),&_bit16,sizeof(Bit16));

#ifdef WIN32
	PrintLutByte("协议头部",(unsigned char *)_ProtocolHead,_ProtocolHeadLen);
#endif

	//printf("\n");
	//printf("首部校验：");
	//printf("%04X ",pProtocolHead->cksum);
	//printf("\n");

	if(_LutPackage == NULL) {
		nRet = -1;
		return nRet;
	}
	_LutPackage->_LutPackageLen = _ProtocolHeadLen + 32 + pEncryptBodyData->BodyDataLen;
	_LutPackage->_LutPackage = (Bit8 *)malloc(_LutPackage->_LutPackageLen);
	memset(_LutPackage->_LutPackage,0,_LutPackage->_LutPackageLen);
	_LutPackageP = _LutPackage->_LutPackage;
	memcpy_s(_LutPackageP,_ProtocolHeadLen,_ProtocolHead,_ProtocolHeadLen);
	_LutPackageP += _ProtocolHeadLen;
	memcpy_s(_LutPackageP,pSecurityKey->SecurityKeyLen,pSecurityKey->pSecurityKeyData,pSecurityKey->SecurityKeyLen);
	_LutPackageP += pSecurityKey->SecurityKeyLen;
	memcpy_s(_LutPackageP,pSignature->SignatureLen,pSignature->pSignatureData,pSignature->SignatureLen);
	_LutPackageP += pSignature->SignatureLen;
	memcpy_s(_LutPackageP,pEncryptBodyData->BodyDataLen,pEncryptBodyData->pBodyDData,pEncryptBodyData->BodyDataLen);
	_LutPackageP += pEncryptBodyData->BodyDataLen;

	//PrintLutByte("完整数据包",_LutPackage->_LutPackage,_LutPackage->_LutPackageLen);
	//if(pSecurityKey != NULL){
	//	if(pSecurityKey->pSecurityKeyData){
	//		free(pSecurityKey->pSecurityKeyData);
	//		pSecurityKey->pSecurityKeyData = NULL;
	//	}
	//	free(pSecurityKey);
	//}
	FreeLutProtocol(pSecurityKey,pSecurityKeyData);
	FreeLutProtocol(pBodyData,pBodyDData);
	FreeLutProtocol(pEncryptBodyData,pBodyDData);
	FreeLutProtocol(pSignature,pSignatureData);

	FreeBuf(pProtocolHead);

	if(_ProtocolHead){
		free(_ProtocolHead);
		_ProtocolHead = NULL;
	}
	nRet = 0;
	return nRet;
}

/************************************************************************/
/* _head	头部返回			4字节									*/			
/* nP2c		数据包指令			3位											*/
/* nDataLen 数据包主体长度		13位								*/
/* nSign	数据包标记位		3位 [保留，是否分片，是否最后片]			*/				
/* offset	数据包偏移量		13位			*/
/* seril	数据包序号			16位			*/
/************************************************************************/
int NewP2PProtocolHead(char * _head,int nP2c,int nDataLen,int nSign,int nOffset,Bit16 serial){
	Bit16 ckSum = 0;
	// 协议头共占4字节（32位）
	_head[0] = (nP2c << 5 & 0xE0) | (nDataLen >> 8 & 0x1F) ;
	//PrintLutByte("P2PHead[0]",_head,1);
	_head[1] = nDataLen & 0xFF;

	_head[2] = (nSign << 5 & 0xE0) | (nOffset >> 8 & 0x1F) ;
	_head[3] = nOffset & 0xFF;

	_head[4] = 0;//ckSum >> 8 && 0xFF;
	_head[5] = 0;//ckSum >> 0 && 0xFF;

	_head[6] = serial >> 8 & 0xFF;
	_head[7] = serial >> 0 & 0xFF;

	ckSum = LutCkSum((Bit8 *)_head,P2P_HEAD_LEN);
	_head[4] = ckSum >> 8 & 0xFF;
	_head[5] = ckSum >> 0 & 0xFF;

	return 0;
}

/** 获取协议头 nP2c值 **/
int GetHeadnP2c(char * _head){
	return (_head[0] & 0xFF )>> 5 & 0x1F;
}

/** 获取nDataLen值 **/
int GetHeadnDataLen(char * _head){
	return (_head[0] &0x1F) << 8 | (_head[1]);
}

/** 获取协议头 nSign值 **/
int GetHeadnSign(char * _head){
	return (_head[2] & 0xFF )>> 5 & 0x1F;
}

/** 获取nOffset值 **/
int GetHeadnOffset(char * _head){
	return (_head[2] &0x1F) << 8 | (_head[3]);
}

/** 获取校验和 **/
int GetHeadCkSum(Bit16 *_ckSum,char * _head){
	Bit16 ckSum = 0;
	ckSum = (_head[4] << 8 & 0xFF00) | (_head[5] << 0 & 0xFF);
	*_ckSum = ckSum;
	return 0;
}

/** 获取数据序号 **/
int GetHeadSerial(Bit16 *_ckSum,char * _head){
	Bit16 ckSum = 0;
	ckSum = (_head[6] << 8 & 0xFF00) | (_head[7] << 0 & 0xFF);
	*_ckSum = ckSum;
	return 0;
}

/** 生成P2P协议数据包头 **/
int NewP2PHead(char * _head,int nP2c,int nDataLen){
	// 协议头占2字节 共16位 从左到右 前3位为指令 后13位是数据长度 最长8192字节
	//int k = 0;
	//for(;k<260;k++){
	//	* _head = k;
	//	PrintLutByte("_head = 1 ==>",_head,2);
	//}
	_head[0] = (nP2c << 5 & 0xE0) | (nDataLen >> 8 & 0x1F) ;
	//PrintLutByte("P2PHead[0]",_head,1);
	_head[1] = nDataLen & 0xFF;
	//PrintLutByte("P2PHead",_head,2);
	return 0;
}
/** 生成P2P数据包 **/
int NewP2PPackage(P2PPackage_t * _p2pPackage,char * _head,Bit8 * szData){
	int nDataLen = 0;
	int nP2c = 0;
	nDataLen = (_head[0] &0x1F) << 8 | (_head[1]);
	_p2pPackage->packageLen = nDataLen;
	memcpy_s(_p2pPackage->package,2,_head,2);
	memcpy_s(_p2pPackage->package+2,nDataLen,szData,nDataLen);
	nP2c = (_head[0] & 0xFF )>> 5 & 0x1F;
	fn_RYN_LOG_DEBUG(TAG,"nDataLen = %d,nP2c = %d",nDataLen,nP2c);
	return 0;
}

/** 计算16位首部校验和 **/
Bit16 LutCkSum(Bit8 * buffer, int size)
{
	unsigned long cksum = 0;
	int i= 0;
	//printf("LutCkSum =");
	//for(i=0;i<size;i++){
	//	printf("%02X ",buffer[i]);
	//}
	//printf("\n");
	while(size>1)
	{
		//cksum += *buffer++;
		//cksum += (*buffer>>8 | *buffer<<8);
		//cksum += _bit16;
		cksum += (buffer[i]&0xFF)<<0x08 | (buffer[i+1]&0xFF);
		//printf("buffer[i]<<0x08 | buffer[i+1] = %02X\n",buffer[i]<<0x08 | buffer[i+1]);
		size -= sizeof(Bit16);
		i += 2;
	}
	if(size)
	{
		cksum += *(Bit8*)buffer;
	}
	cksum = (cksum>>16) + (cksum&0xffff); 
	cksum += (cksum>>16);
	// unsigned long 占4字节 Bit16占2字节
	// 将高16位移到低16位进行强转
	return (Bit16)(~cksum);
}

int LutRandom(int ran,int tm){
	// 初始化随机数种子（仅首次调用时执行，避免重复初始化）
	static bool is_seed_initialized = false;
    if (!is_seed_initialized) {
        srand(time(NULL));  // 使用系统时间初始化标准随机数种子
        is_seed_initialized = true;
    }

    // 处理输入参数
    if (ran <= 0) {
        return 0;
    }

    // 生成随机数（结合ESP-IDF随机函数和标准库函数）
    uint32_t random_value = esp_random();  // 硬件随机数（0~0xFFFFFFFF）
    return (int)(random_value % ran);  // 映射到[0, ran-1]范围
}

int GetUserAgentLocalIP(){
#ifdef WIN32
	WORD v = MAKEWORD(1, 1);
	int i = 0;
	WSADATA wsaData;    
	struct hostent *phostinfo;
	WSAStartup(v, &wsaData); // 加载套接字库
	phostinfo = (struct hostent *)gethostbyname("");
	for(i = 0; NULL != phostinfo&& NULL != phostinfo->h_addr_list[i]; ++i)  
	{
		char *pszAddr = inet_ntoa(*(struct in_addr *)phostinfo->h_addr_list[i]);  
		//printf("32位IP地址：%s\n", pszAddr);
		if(phostinfo->h_addrtype)
		return inet_addr(pszAddr);
	}
#endif
	return 0;
}

/** 数据包计数器 **/
Bit16 GetDataSerial(){
	if(nGLdataSerial >= 0xFFFF || nGLdataSerial <= 0x00){
		nGLdataSerial = 0x01;
	}else{
		nGLdataSerial++;
	}
	return nGLdataSerial;
}

/** 本机设备码 **/
int GetNativeDeviceCode(Bit8 * szUserAgent,int * nUserAgentLen){
	Bit8     szUserAgentByte[16] = {0};
	MD5Context_t md5Ctx;
	uint8_t	szSerialNumberHex[128] ={0};
	esp_read_mac(szSerialNumberHex, ESP_MAC_WIFI_STA);

	MD5Init(&md5Ctx);
	MD5Update(&md5Ctx,(unsigned char *)szSerialNumberHex,strlen((char * )szSerialNumberHex));
	MD5Final(szUserAgentByte,&md5Ctx);
	//printf("szCPUID = %s\n",szCPUID);
	//printf("szUserAgent = ");
	//for(i=0;i<16;i++)
	//	printf("%02X ",szUserAgentByte[i]);
	ByteToHexStr(szUserAgentByte,(char *)szUserAgent,16);
	//printf("== szUserAgent = %s\n",szUserAgent);
	*nUserAgentLen = strlen((char *)szUserAgent);
	
	return 0;
}


/** 对比字节数组值是否相等 **/
int CompareArray(unsigned char *str,unsigned char *str1,int offset,int limit)
{
	int i,j=0;
	for(i=offset;i<limit;i++)
	{
		if((str[i]&0xFF) > (str1[i]&0xFF)){j=1;break;}
		else if((str[i]&0xFF) < (str1[i]&0xFF)){j=-1;break;}
	}
	return j;
}

void AES_Encrypt_Len(unsigned int plainTextLen,unsigned int *cliperTextLen){
	*cliperTextLen = (plainTextLen / 16) * 16 + 16;
}